package com.lingz.manager.modules.camera.utils;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpMethod;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
public class HuaweiHttpDigestUtils {

    private final static Splitter sp_quote = Splitter.on(",").trimResults().omitEmptyStrings();
    private final static Joiner join_auth = Joiner.on(":").skipNulls();
    private final static Joiner join_quote = Joiner.on(", ").skipNulls();
    public static final String DIGEST = "Digest ";


    private static String encode(String type, String text) {
        if (StringUtils.equals(type, "MD5")) {
            return DigestUtils.md5Hex(text);
        } else if (StringUtils.equals(type, "SHA-256")) {
            return DigestUtils.sha256Hex(text);
        } else {
            Preconditions.checkState(false, "无法识别的密码加密方式", type);
        }
        return null;
    }
    private static String trim (String src,String flag){
        return StringUtils.removeStart(StringUtils.removeEnd(src,flag),flag);
    }

    @SneakyThrows
    public static String authorizationHeader(String wwwAuthenticate, String url, HttpMethod httpMethod, String username, String password){
        final Map<String, String> wwwAuthMap = Optional.of(wwwAuthenticate).map(s -> StringUtils.removeStart(s, DIGEST))
                .map(s -> sp_quote.splitToList(s).stream().collect(
                        Collectors.toMap(
                                a -> StringUtils.substringBefore(a, "="),
                                a -> StringUtils.substringAfter(a, "="),
                                (a, b) -> b
                        ))
                ).get();

        String auth_resp = Optional.of(wwwAuthMap).map(info -> {
            String algorithm = info.get("algorithm");// SHA-256/MD5
            String realm = trim(info.get("realm"),"\"");
            String ha1 = join_auth.join(Lists.newArrayList(username, realm, password));
            //String HA1 = encode(algorithm, ha1);
            String HA1 = encode("MD5", ha1);
            log.debug("计算HA1（加密方式: {}）-> \r\n 原文-> {}\r\n 密文-> {}\r\n",algorithm,ha1,HA1);
            String uri = "/"+StringUtils.substringAfter(StringUtils.substringAfter(url,"//"),"/");
            String ha2 = join_auth.join(Lists.newArrayList(httpMethod.toString(), uri));
            //String HA2 = encode(algorithm, ha2);
            String HA2 = encode("MD5", ha2);
            log.debug("计算HA2（加密方式: {}）-> \r\n 原文-> {}\r\n 密文-> {}\r\n",algorithm,ha2,HA2);

            String nonce = trim(Objects.toString(info.get("nonce")),"\"");
            String respOri = join_auth.join(Lists.newArrayList(
                    HA1,
                    nonce,
                    HA2
            ));
            //String authResponse = encode(
            //        algorithm,
            //        respOri);
            String authResponse = encode(
                    "MD5",
                    respOri);

            log.debug("计算response（加密方式: {}）-> \r\n 原文-> {}\r\n 密文-> {}\r\n",algorithm,respOri,authResponse);
            return DIGEST + join_quote.join(
                    String.format("username=\"%s\"", username),
                    String.format("realm=\"%s\"", realm),
                    String.format("nonce=\"%s\"", nonce),
                    String.format("uri=\"%s\"", uri),
                    String.format("algorithm=\"%s\"", algorithm),
                    String.format("response=\"%s\"", authResponse)
            );
        }).get();

        log.debug("--> header-> \r\n{}",auth_resp);
        return auth_resp;
    }

    public static void main(String[] args) {
        String header = authorizationHeader("MD5",
                "https://192.168.1.19/SDCAPI/V2.0/Metadata/Subscription?ID=1",
                HttpMethod.GET,
                "ApiAdmin",
                "HuaWei1234");
    }

}
